// Copyright 2023 ztlcloud.com
// leovs @2023.12.12

package conf

import (
	"embed"
	"fmt"
	"gitee.com/leovs/yc-go-sdk/log"
	"gitee.com/leovs/yc-go-sdk/sdk"
	"github.com/go-mysql-org/go-mysql/canal"
	"github.com/go-mysql-org/go-mysql/mysql"
	"gopkg.in/yaml.v3"
	"os"
	"time"
)

const (
	cfgFile  = "config.%s.yaml"
	LOCATION = "Asia/Shanghai"
)

type Settings struct {
	Mode           string                 `yaml:"mode"`       // 运行模式
	AppName        string                 `yaml:"appName"`    // 应用名称
	Port           int                    `yaml:"port"`       // 端口
	Version        string                 `yaml:"version"`    // 版本
	EurekaConfig   *EurekaConfig          `yaml:"eureka"`     // 服务注册
	RedisConfig    *RedisConfig           `yaml:"redis"`      // Redis配置
	ServerConfig   *ServerConfig          `yaml:"server"`     // Gin配置
	DatabaseConfig *DatabaseConfig        `yaml:"dataSource"` // 数据库配置
	CanalConfig    *CanalConfig           `yaml:"canal"`      // Canal配置
	EsConfig       *EsConfig              `yaml:"es"`         // ES配置
	Customize      map[string]interface{} `yaml:"customize"`  // 自定义配置
	FS             *embed.FS              `yaml:"-"`          // embed
}

// Setup 载入配置文件
func (e *Settings) Setup(env string) {
	conStr, err := os.ReadFile(fmt.Sprintf(cfgFile, env))
	if err != nil {
		log.Panic("读取配置文件失败", err)
		return
	}

	if err := yaml.Unmarshal(conStr, &e); err != nil {
		log.Panic("解析配置文件失败", err)
		return
	}

	// 初始化配置
	e.Init()
}

// 初始化全局变量
func (e *Settings) initConfig() {
	for k, v := range e.Customize {
		sdk.Runtime.SetConfig(k, v)
		log.Debug("自定义配置", k, v)
	}
	sdk.Runtime.Mode(e.Mode)
}

// Init 初始化配置
func (e *Settings) Init() {
	// 设置时区
	_, _ = time.LoadLocation(LOCATION)

	// 初始化参数
	e.initConfig()
	// 初始化Redis
	e.RedisConfig.Init(e)
	// 初始化数据库
	e.DatabaseConfig.Init(e)
	// eureka注册
	e.EurekaConfig.Init(e)
	// service注册
	e.ServerConfig.Init(e)
	// 初始化ES
	e.EsConfig.Init(e)

}

func (e *Settings) SetRouter(routers ...sdk.IRouter) {
	engine := sdk.Runtime.GetEngine()
	for _, router := range routers {
		router.InitRouter(&sdk.Router{Engine: engine})
	}
}

func (e *Settings) InitCanal(pos *mysql.Position, eventHandler canal.EventHandler) {
	// 初始化Canal
	if e.CanalConfig == nil {
		log.Error("Canal配置为空，跳过初始化")
		return
	}

	e.CanalConfig.SetEventHandler(eventHandler)
	e.CanalConfig.SetPost(pos)
	e.CanalConfig.Init()
}

func (e *Settings) Run() {
	err := sdk.Runtime.GetEngine().Listen(fmt.Sprintf(":%d", e.Port))
	if err != nil {
		log.Panic("启动服务失败", err.Error())
	}
}
